/**
 * 文件名：@NetstedPropertyEditor.java <br/>
 * 包名：cn.efunbox.afw.core.bean <br/>
 * 项目名：afw-core <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.core.bean;

import java.beans.PropertyDescriptor;
import java.util.Map;

/**
 * 类名：NetstedPropertyEditor  <br />
 *
 * 功能：使用.号进行导航的属性编辑器
 *
 * @author xtwin <br />
 * 创建时间：2015年12月4日 下午3:34:24  <br />
 * @version 2015年12月4日
 */
public class NetstedPropertyEditor implements PropertyEditor {
	
	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2015年12月4日 下午3:34:58<br/>
	 * 
	 * @param root
	 * @param property
	 * @param value
	 * @throws Exception <br/>
	 * @see cn.efunbox.afw.core.bean.PropertyEditor#setValue(java.lang.Object, java.lang.String, java.lang.Object)
	 */
	@Override
	public void setValue(Object root, String property, Object value) throws Exception {
		
		// 执行编辑
		doSet(root, property, value);
	}

	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2015年12月8日 上午11:23:12<br/>
	 * 
	 * @param root
	 * @param property
	 * @return
	 * @throws Exception <br/>
	 * @see cn.efunbox.afw.core.bean.PropertyEditor#getValue(java.lang.Object, java.lang.String)
	 */
	@Override
	public Object getValue(Object root, String property) throws Exception {
		
		// 执行读取值
		return doGetValue(root, property);
	}
	
	/**
	 * 功能：读取值 <br/>
	 * 
	 * 		暂时先不考虑map的key中包含点好的情况
	 *
	 * @author xtwin <br/>
	 * @version 2015年12月8日 上午11:24:49 <br/>
	 */
	@SuppressWarnings("rawtypes")
	protected Object doGetValue(Object root, String netsted) throws Exception {
		
		if (null == root) {
			return null;
		}
		
		int index = netsted.indexOf('.');
		
		String property = netsted;
		if (index != -1) {
			property = netsted.substring(0, index);
		}
		
		Object value = null;
		if (root instanceof Map) {
			value = ((Map) root).get(property);
		} else {
			// 读取属性值
			value = new PropertyDescriptor(property, root.getClass()).getReadMethod().invoke(root);
		}
		
		if (index != -1) {
			// 执行递归取值
			value = doGetValue(value, netsted = netsted.substring(index + 1));
		}
		
		return value;
	}
	/*protected Object doGetValue(Object root, String netsted) throws Exception {
		
		if (null == root) {
			return null;
		}
		
		int index = netsted.indexOf('.');
		
		String property = netsted;
		if (index != -1) {
			property = netsted.substring(0, index);
		}
		
		Object value = null;
		if (root instanceof Map) {
			value = ((Map) root).get(property);
		} else {
			// 读取属性值
			value = new PropertyDescriptor(property, root.getClass()).getReadMethod().invoke(root);
		}
		
		if (index != -1) {
			// 执行递归取值
			value = doGetValue(value, netsted = netsted.substring(index + 1));
		}
		
		return value;
	}*/

	/**
	 * 
	 * 功能：更新值 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2015年12月4日 下午3:35:54 <br/>
	 */
	protected void doSet(Object inst, String netsted, Object value) throws Exception {
		int index = netsted.indexOf('.');
		
		String property = netsted;
		
		if (index != -1) {
			property = netsted.substring(0, index);
			
			netsted = netsted.substring(index + 1);
		}
		
		// 创建属性描述
		PropertyDescriptor pdesc = new PropertyDescriptor(property, inst.getClass());
		
		Object _v = value;
		if (index != -1) {
			// 复杂类型，要递归处理
			_v = pdesc.getReadMethod().invoke(inst);
			
			if (null == _v) {
				_v = pdesc.getPropertyType().newInstance();
			}
			
			doSet(_v, netsted, value);
		}
		
		pdesc.getWriteMethod().invoke(inst, _v);
	}
}